package com.kfm.login.interceptor;

import com.kfm.login.exception.LoginException;
import com.kfm.login.util.Constant;
import com.kfm.login.util.IPUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * 连续登录失败 指定次数，加入黑名单
 */
@Component
public class LoginCountInterceptor implements HandlerInterceptor {

    @Resource
    private RedisTemplate<String, Integer> redisTemplate;

    @Value("${login.maxLoginCount}")
    private Integer maxCount;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ip = IPUtils.getIpAddress(request); // 获取ip
        String key = Constant.REDIS_LOGIN_PREFIX + ip; // 按照指定的前缀设置key
        Integer count = redisTemplate.opsForValue().get(key);
        if (count == null) {
            // 第一次请求
            redisTemplate.opsForValue().set(key, 1);
            return true;
        }
        count = count + 1;
        if (count >= maxCount) { // 超过最大访问次数
            // 将 ip 保存为拉黑模式，24小时
            redisTemplate.opsForValue().set(Constant.REDIS_BLACK_PREFIX + ip, 1, 24, TimeUnit.HOURS);
            // 自定义异常
            throw new LoginException(401, "错误次数上限");
        }
        redisTemplate.opsForValue().set(key, count); // 没有超过最大访问次数 key对应的value自增
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        // 如果登录成功，删除redis中ip对应的key
        if (request.getAttribute("login") != null) {
            String key = Constant.REDIS_LOGIN_PREFIX + IPUtils.getIpAddress(request);
            redisTemplate.delete(key);
        }

    }
}
